home *** CD-ROM | disk | FTP | other *** search
- /* luminanceMeter.c
-
- Macintosh c-routines that can be used to read out the Minolta LS-110/100 luminance meters
- using the RS-232 output.
-
- Please send suggestions, bugs, improvements, comments to f.w.cornelissen@med.rug.nl
- Further details in read me file. Use at your own risk.
-
- Your program needs to open a serial port using "initLuminanceMeter(PORT)". Set PORT to the port to
- which you connected your meter to (either the printer or modem port) using the
- #define PORT PRINTER_PORT/MODEM_PORT statement.
-
- You can then read the luminance values using "getLuminance()". Get luminance takes a pointer to a double (lum)
- in which to store the luminance value, and a pointer to a string (message) to store the other stuff in the
- luminance meter outputs. You don't really need this info to make measurements.
-
- Once you're finished with measuring you should close the connection using "endLuminanceMeter( )". That's all.
-
- There's a convenience routine "returnPortName()" that you can use to print out the port for which the
- program is configured.
-
- Make sure you put #include "luminanceMeter.h" into your code.
-
-
- program example
-
- #include "luminanceMeter.h"
-
- void main( void )
- {
- int i;
- double lum;
- char message[255];
-
- initLuminanceMeter( MODEM_PORT );
-
- printf( "\nMeasuring luminance\n" );
- for( i = 0; i < 10; i ++ )
- {
- getLuminance( &lum, message );
- printf( "Measurement: %d, Luminance: %f, message: %s\n", i, luminance, message );
- }
-
- endLuminanceMeter();
- }
-
- ************************************************************************
-
- 27-06-92 FWC created first mac version, based partly on Atari software by Lars Jansen.
- 05-09-95 FWC cleaned up, translated comments into english, Eli Brenner suggested a better way to do the
- character to float conversion
- 21-02-97 fwc new code, system 7.5 compatible based partly on code from Inside Macintosh
- (and after suggestions from Hiro Akutsu). The code first checks if there's a
- message available, so it no longer hogs the computer. Support for sending measurements
- requests added.
- 26-02-97 fwc removed the SLOW parameter as it wasn't really necessary to use this. Changed the
- strings that returned driver names.
-
- ************************************************************************ */
-
-
-
- #include "luminanceMeter.h"
-
- // driver reference numbers
- short int gOutputRefNum; // output driver reference number
- short int gInputRefNum; // input driver reference number
-
- // strings used by the routines below
-
- unsigned char *serialDriverString[][2] = { "\p.AOut", "\p.AIn", "\p.BOut", "\p.BIn" };
- char *portNameString[] = { "ModemPort", "PrinterPort" };
-
-
-
- int initLuminanceMeter( portType port )
- {
- if( openSerialDriver( port ) )
- {
- if( setHandshakeOptions() )
- if( configureSerialPort() )
- {
- setDTR(HIGH); // setDTR high all the time
- return( true );
- }
- serialDriverStatusCheck();
- closeSerialDriver();
- }
- printf( "\n initLuminanceMeter(): error: could not open serial driver or port." );
- return( false );
- }
-
- int getLuminance( double *lum, char *message )
- {
- ParamBlockRec par;
- char buffer[ MESSAGE_LENGTH ];
- double time;
- OSErr error;
-
- // init parameterBlock
-
- par.ioParam.ioRefNum = gInputRefNum; // input driver number
- par.ioParam.ioBuffer = buffer; // buffer address
- par.ioParam.ioReqCount = MESSAGE_LENGTH; // no count yet
- par.ioParam.ioCompletion = NULL;
- par.ioParam.ioVRefNum = 0;
- par.ioParam.ioPosMode = 0;
-
- if( clearSerialBuffer() )
- {
- sendMeasurementRequest();
- // if there is no message, PBReadSync() below waits indefinetely
- // so we first check whether there is an appropriately sized message
- if( !checkMeasurementPresent( &time ) )
- {
- sprintf( message, "No response from luminance meter after %2.2f secs", time );
- *lum = -1.0;
- return( false );
- }
- else
- {
- // when a complete message is available, read it
- error = PBReadSync( &par ); // if there is no message, this function would wait indefinetely
- if( error != noErr )
- {
- printf( "\n getLuminance(): error reading input serial buffer" );
- serialDriverStatusCheck( );
- return( false );
- }
- }
- }
- else
- return( false );
-
- buffer[10]=0; // replace character return by 0
- *lum = atof( &buffer[4] );
- sprintf( message, "Mode: %c, Unit: %c, Calibration: %c, Measurement: %c", buffer[0], buffer[1], buffer[2], buffer[3] );
-
- return( true );
- }
-
- char *returnPortName( portType port )
- {
- return( portNameString[ port ] );
- }
-
-
- int checkMeasurementPresent( double *t )
- {
- int wait = true;
- clock_t start;
-
- start = clock();
- while( checkSerialBuffer() < MESSAGE_LENGTH && wait ) // wait while there is no complete message yet
- if( ( *t = ( clock() - start) / 60.0 ) > PATIENCE ) wait = false;
- return( wait );
- }
-
- // the minolta manual specifies that setting the request signal to low is the way to get a
- // measurement going. I've tried to increase the signal followed (within ~1 sec by a decrease,
- // couldn't get the thing to output any data. I now set the signal high when initialising the
- // driver and meter, and only briefly (~0.1 s) decrease the signal. This is sufficient to get a
- // measurement.
-
- int sendMeasurementRequest( void )
- {
- OSErr error;
- clock_t start;
-
- error = Control(gOutputRefNum, LOW, NULL );
-
- if( error != noErr )
- {
- printf( "\n sendMeasurementRequest(): error setting DTR LOW" );
- return( false );
- }
-
- start = clock();
- while( ( ( clock() - start) / 60.0 ) < REQUEST_LOW_TIME ) ;
-
- error = Control(gOutputRefNum, HIGH, NULL );
-
- if( error != noErr )
- {
- printf( "\n sendMeasurementRequest(): error setting DTR HIGH" );
- return( false );
- }
- return( true );
- }
-
-
- int checkSerialBuffer( void )
- {
- OSErr error;
- long count;
- error = SerGetBuf( gOutputRefNum, &count );
- if( error != noErr )
- {
- printf( "\n checkSerialBuffer(): error checking output serial buffer count (%d)", count );
- return( false );
- }
- return( (int) count );
- }
-
-
- int setDTR( dtrType dtr )
- {
- OSErr error;
- error = Control(gOutputRefNum, dtr, NULL ); // set DTR high or low (+5V or -5V at DTR pin)
- if( error != noErr )
- {
- printf( "\n setDTR(): error setting DTR %s", dtr==HIGH?"high":"low" );
- return( false );
- }
- return( true );
- }
-
-
- int setHandshakeOptions( void )
- {
- // Set flow control method and other options. Note that you only need to set
- // the output driver; the settings are reflected on the input side.
- OSErr error;
- SerShk serShkRec; // serial handshake record
-
- serShkRec.fXOn = 0; // 0 {turn off XON/XOFF output flow control}
- serShkRec.fCTS = 1; // 1 = to do hardware control, we'll be using the DTR line to control the photometer trigger (+5V and -5V). */
- serShkRec.xOn = 0;
- serShkRec.xOff = 0;
- serShkRec.errs = 0; // clear error mask
- serShkRec.evts = 0; // clear event mask
- serShkRec.fInX = 0; // 1 = turn on XON/XOFF input flow control
- serShkRec.fDTR = 1; // set to 0 to turn off DTR input flow control
-
- error = Control(gOutputRefNum, 14, &serShkRec); // this is the serHandShake call that allows one to set DTR control
- if( error != noErr )
- {
- printf( "\n setHandshakeOptions(): error setting handshake options" );
- return( false );
- }
- return( true );
- }
-
-
- int clearSerialBuffer( void )
- {
- OSErr error;
- error = KillIO( gOutputRefNum );
- if( error != noErr )
- {
- printf( "\n clearSerialBuffer(): error clearing output serial buffer" );
- return( false );
- }
- // although Inside Mac specifies that it is not necessary to kill the IO for the input
- // buffer, I had the impression it occasionally worked better when I did it anyway.
- error = KillIO( gInputRefNum );
- if( error != noErr )
- {
- printf( "\n clearSerialBuffer(): error clearing input serial buffer" );
- return( false );
- }
- return( true );
- }
-
-
- int configureSerialPort( void )
- {
- int configParam;
- OSErr error;
- configParam = baud4800 + data7 + stop20 + evenParity; // constants defined in "serial.h"
- error = SerReset( gOutputRefNum, configParam );
- if( error != noErr )
- {
- printf( "\n configureSerialPort(): error configuring output port" );
- return( false );
- }
- return( true );
- }
-
-
-
- int openSerialDriver( portType port )
- {
- // use the device mananger OpenDriver() function to open the drivers
-
- OSErr error;
-
- error = OpenDriver( returnDriverString( port, OUTPUT ), &gOutputRefNum ); // always open output driver first
-
- if( error != noErr )
- {
- printf( "\n openSerialDriver(): error opening output driver" );
- return( false );
- }
-
- error = OpenDriver( returnDriverString( port, INPUT ), &gInputRefNum ); // then open input driver
-
- if( error != noErr )
- {
- printf( "\n openSerialDriver(): error opening input driver" );
- error = CloseDriver( gOutputRefNum ); // close output driver
- return( false );
- }
-
- return( true );
- }
-
-
- int closeSerialDriver( void )
- {
- OSErr error;
- error = KillIO( gOutputRefNum ); // terminate all pending I/O operations
- if( error != noErr )
- {
- printf( "\n closeSerialDriver(): KillIO() error" );
- return( false );
- }
-
- error = CloseDriver(gInputRefNum); // close the input driver first
-
- if( error != noErr )
- {
- printf( "\n closeSerialDriver(): error closing input driver" );
- return( false );
- }
-
- error = CloseDriver(gOutputRefNum); // then close the output driver
- if( error != noErr )
- {
- printf( "\n closeSerialDriver(): error closing output driver" );
- return( false );
- }
- return( true );
- }
-
-
-
-
- int serialDriverStatusCheck( void )
- {
- // to check the Serial Driver status. see.7-25 in the Inside-Macintosh
- SerStaRec status;
- int breakErr = 8;
- OSErr error;
-
- error = SerStatus(gInputRefNum,&status);
-
- if( error || status.cumErrs)
- printf("\n Serial Driver status check: OSErr %d, cumErrs %d, rdPend %d, ctsHold %d, xOffHold %d --- ",
- error, status.cumErrs, status.rdPend, status.ctsHold, status.xOffHold );
- else
- printf("\n Serial Driver status check: no errors");
- if(status.cumErrs & swOverrunErr) printf("\n software overrun error.\n");
- if(status.cumErrs & breakErr) printf("\n break signal asserted.\n");
- if(status.cumErrs & parityErr) printf("\n parity error.\n");
- if(status.cumErrs & hwOverrunErr) printf("\n hardware overrun error.\n");
- if(status.cumErrs & framingErr) printf("\n framing error.\n");
- if(status.cumErrs & swOverrunErr) printf("\n software overrun error.\n");
-
- return( status.cumErrs );
- }
-